package org.openlca.ilcd.util; import java.io.BufferedInputStream; import java.io.InputStream; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import javax.xml.XMLConstants; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.openlca.ilcd.commons.DataSetType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.ErrorHandler; public class SchemaValidator { private ErrorHandler errorHandler; private Logger log = LoggerFactory.getLogger(getClass()); private HashMap<DataSetType, Schema> schemas = new HashMap<>(10); public void setErrorHandler(ErrorHandler h) { this.errorHandler = h; } public boolean isValid(Path path, DataSetType type) { if (path == null) return false; Validator val = makeValidator(type); if (val == null) return false; try (BufferedInputStream is = new BufferedInputStream( Files.newInputStream(path))) { val.validate(new StreamSource(is)); return true; } catch (Exception e) { log.error("validation of {} failed: {}", path, e.getMessage()); return false; } } public boolean isValid(InputStream stream, DataSetType type) { if (stream == null) return false; Validator val = makeValidator(type); if (val == null) return false; try { val.validate(new StreamSource(stream)); return true; } catch (Exception e) { log.error("validation failed: {}", e.getMessage()); return false; } } private Validator makeValidator(DataSetType type) { Schema s = schema(type); if (s == null) { log.error("could not load a schema for type {}", type); return null; } Validator val = s.newValidator(); if (errorHandler != null) val.setErrorHandler(errorHandler); return val; } private Schema schema(DataSetType type) { if (type == null) return null; Schema s = schemas.get(type); if (s != null) return s; s = loadSchema(schemaName(type)); schemas.put(type, s); return s; } private String schemaName(DataSetType type) { if (type == null) return null; switch (type) { case CONTACT: return "ILCD_ContactDataSet.xsd"; case FLOW: return "ILCD_FlowDataSet.xsd"; case FLOW_PROPERTY: return "ILCD_FlowPropertyDataSet.xsd"; case LCIA_METHOD: return "ILCD_LCIAMethodDataSet.xsd"; case PROCESS: return "ILCD_ProcessDataSet.xsd"; case SOURCE: return "ILCD_SourceDataSet.xsd"; case UNIT_GROUP: return "ILCD_UnitGroupDataSet.xsd"; default: log.error("no schema available for data set type {}", type); return null; } } private Schema loadSchema(String name) { if (name == null) return null; try { URL url = SchemaValidator.class.getResource("/ilcd/schemas/" + name); SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); return factory.newSchema(url); } catch (Exception e) { log.error("failed to load schema " + name, e); return null; } } }